<template>
  <div class="graph-container">
    <!-- 顶部标题和操作区域 -->
    <div class="top-header">
      <div class="page-title">
        <h2>{{subjectList.find(s => s.id === selectedSubject)?.name}}知识图谱管理</h2>
        <p class="subtitle">管理和可视化知识点结构</p>
      </div>
      
      <div class="top-actions">
        <el-select
          v-model="selectedSubject"
          placeholder="请选择学科"
          @change="handleSubjectChange"
          class="subject-select"
        >
          <el-option
            v-for="item in subjectList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
        
        <!-- <el-radio-group 
          v-model="displayMode" 
          @change="handleModeChange"
          class="display-toggle"
        >
          <el-radio-button label="table">表格视图</el-radio-button>
          <el-radio-button label="chart">图形视图</el-radio-button>
        </el-radio-group> -->
      </div>
    </div>

    <!-- 内容区域卡片 -->
    <el-card class="main-content-card" :body-style="{ padding: '0px' }">
      <!-- 图形视图模式 -->
      <div class="chart-view">
        <div id="knowledgeChart" class="knowledge-chart"></div>
      </div>
      <!-- 表格视图模式 -->
      <div class="table-view">
        <!-- 工具栏 -->
        <div class="table-toolbar">
          <div class="filter-section">
            <el-input
              v-model="searchKeyword"
              placeholder="搜索知识点..."
              class="search-input"
              clearable
              @input="handleSearch"
            >
              <template #prefix>
                <el-icon><Search /></el-icon>
              </template>
            </el-input>
            
            <div class="filter-dropdowns">
              <el-select 
                v-model="filterChapter" 
                placeholder="按章节筛选" 
                clearable 
                @change="handleFilter"
                class="filter-select"
              >
                <el-option 
                  v-for="chapter in chapterOptions" 
                  :key="chapter" 
                  :label="`第${chapter}章`" 
                  :value="chapter" 
                />
              </el-select>
              
              <el-select 
                v-model="filterMastery" 
                placeholder="按掌握程度筛选" 
                clearable 
                @change="handleFilter"
                class="filter-select"
              >
                <el-option label="了解" value="了解" />
                <el-option label="理解" value="理解" />
                <el-option label="掌握" value="掌握" />
                <el-option label="应用" value="应用" />
              </el-select>
            </div>
          </div>
          
          <div class="action-buttons">
            <el-button 
              type="success" 
              @click="handleExportChapter"
              :disabled="!filterChapter"
              class="export-btn"
            >
              <el-icon><Download /></el-icon>
              导出当前章节
            </el-button>
            
            <el-button type="primary" @click="handleAdd">
              <el-icon><Plus /></el-icon>
              添加知识点
            </el-button>
            <el-button type="warning" @click="handleBatchImport">
              <el-icon><Upload /></el-icon>
              批量导入
            </el-button>
          </div>
        </div>

        <!-- 数据表格 -->
        <el-table
          :data="paginatedData"
          border
          stripe
          highlight-current-row
          style="width: 100%"
          v-loading="loading"
          class="knowledge-table"
        >
          <el-table-column prop="subjectName" label="课程" width="100" />
          <el-table-column prop="chapter" label="章" width="60" sortable align="center" />
          <el-table-column prop="node" label="节" width="60" sortable align="center" />
          <el-table-column prop="knowledge" label="知识点" min-width="220" show-overflow-tooltip />
          <el-table-column prop="mastery" label="掌握程度" width="120" align="center">
            <template #default="scope">
              <el-tag :type="getMasteryTagType(scope.row.mastery)" effect="dark" size="small">
                {{ scope.row.mastery }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="difficulty" label="难度系数" width="120" sortable align="center">
            <template #default="scope">
              <el-rate
                v-model="scope.row.difficulty"
                disabled
                :max="3"
                :colors="difficultyColors"
                text-color="#909399"
              />
            </template>
          </el-table-column>
          <el-table-column label="操作" width="160" align="center">
            <template #default="scope">
              <div class="table-actions">
                <el-button
                  size="small"
                  type="primary"
                  circle
                  @click="handleEdit(scope.row)"
                  title="编辑"
                >
                  <el-icon><Edit /></el-icon>
                </el-button>
                <el-button
                  size="small"
                  type="danger"
                  circle
                  @click="handleDelete(scope.row)"
                  title="删除"
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </div>
            </template>
          </el-table-column>
        </el-table>
        
        <!-- 分页控件 -->
        <div class="pagination-wrapper">
          <el-pagination
            v-model:current-page="currentPage"
            v-model:page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="filteredData.length"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
            background
          />
        </div>
      </div>

 
    </el-card>

    <!-- 选中的章节信息面板 -->
    <el-collapse-transition>
      <el-card v-if="selectedChapterText" class="selected-chapter-panel">
        <div class="panel-header">
          <div class="header-left">
            <h3>{{ selectedChapterName }} 知识点</h3>
            <el-tag type="success" size="small">{{ selectedChapterKnowledgeCount }} 个知识点</el-tag>
          </div>
          <div class="header-actions">
            <el-button 
              type="primary" 
              size="small" 
              @click="saveToTextContent"
            >
              <el-icon><Position /></el-icon>
              保存到题目生成区
            </el-button>
            <el-button 
              type="info" 
              size="small" 
              @click="copyToClipboard"
            >
              <el-icon><DocumentCopy /></el-icon>
              复制内容
            </el-button>
            <el-button 
              type="danger" 
              size="small" 
              circle
              @click="clearSelectedChapter"
            >
              <el-icon><Close /></el-icon>
            </el-button>
          </div>
        </div>
        
        <div class="preview-content">
          <el-input
            type="textarea"
            v-model="selectedChapterText"
            :rows="12"
            resize="none"
            class="preview-textarea"
          />
        </div>
      </el-card>
    </el-collapse-transition>

    <!-- 添加/编辑对话框 -->
    <el-dialog
      v-model="dialogVisible"
      :title="dialogType === 'add' ? '添加知识点' : '编辑知识点'"
      width="50%"
      custom-class="knowledge-dialog"
    >
      <el-form
        :model="formData"
        :rules="formRules"
        ref="formRef"
        label-width="120px"
      >
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="章节" prop="chapter">
              <el-input-number v-model="formData.chapter" :min="1" :max="99" controls-position="right" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="节点" prop="node">
              <el-input-number v-model="formData.node" :min="1" :max="99" controls-position="right" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="知识点" prop="knowledge">
          <el-input v-model="formData.knowledge" type="textarea" :rows="3" />
        </el-form-item>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="掌握程度" prop="mastery">
              <el-select v-model="formData.mastery" placeholder="请选择掌握程度" style="width: 100%">
                <el-option label="了解" value="了解" />
                <el-option label="理解" value="理解" />
                <el-option label="掌握" value="掌握" />
                <el-option label="应用" value="应用" />
                <el-option label="创新" value="创新" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="难度系数" prop="difficulty">
              <el-rate
                v-model="formData.difficulty"
                :max="3"
                :colors="difficultyColors"
                show-score
              />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="submitForm">确 定</el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 批量导入对话框 -->
    <el-dialog v-model="importDialogVisible" title="批量导入知识点" width="60%" custom-class="import-dialog">
      <div class="import-instructions">
        <el-alert
          title="使用AI自动分析知识点内容，生成结构化数据"
          type="info"
          description="请输入知识点内容文本，系统将自动解析生成知识图谱。支持复制粘贴课程大纲、教材目录等内容。"
          :closable="false"
          show-icon
        />
      </div>
      <el-form :model="importForm" label-width="120px">
        <el-form-item label="知识点内容">
          <el-input
            type="textarea"
            v-model="importForm.message"
            :rows="15"
            placeholder="请输入知识点内容，系统将自动解析生成知识图谱"
            class="import-textarea"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="importDialogVisible = false">取 消</el-button>
          <el-button type="primary" @click="submitImport" :loading="importing">
            开始解析
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
  <GenerateQuestion/>
</template>

<script setup>
import { ref, onMounted, nextTick, watch, onUnmounted, computed } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import * as echarts from 'echarts';
import GenerateQuestion from "../../components/home/Step3.vue"
import { useTextContent } from '../../stores/textContent';
import { useRoute } from 'vue-router';
// 引入API
import { getAllGraphData, getGraphDataById, getGraphDataBySubjectId, addGraphData, 
         batchAddGraphData, updateGraphData, deleteGraphData, deleteGraphDataBySubjectId } from '@/api/graph';
import { generateGraphData, generateGraphDataStream } from '@/api/ai';
import { getSubjects } from '@/api/subject'; 

// 使用pinia store
const textContentStore = useTextContent();
const route = useRoute();
// 引入Element Plus图标组件
import {
  Search,
  Plus,
  Edit,
  Delete,
  Download,
  Upload,
  Position,
  DocumentCopy,
  Close
} from '@element-plus/icons-vue';

// 响应式数据定义
const subjectList = ref([]);
const selectedSubject = ref(null);
const graphDataList = ref([]);
const displayMode = ref('chart');
const loading = ref(false);
const importing = ref(false);
const dialogVisible = ref(false);
const importDialogVisible = ref(false);
const dialogType = ref('add');
const formRef = ref(null);

// 图表实例
let chartInstance = null;

// 定义颜色和标签类型
const difficultyColors = ['#67C23A', '#E6A23C', '#F56C6B', '#409EFF', '#909399'];
const masteryTagMap = {
  '了解': 'info',
  '理解': 'success',
  '掌握': 'primary',
  '应用': 'warning',
};

// 初始化表单数据
const formData = ref({
  id: null,
  subjectId: null,
  chapter: 1,
  node: 1,
  knowledge: '',
  mastery: '理解',
  difficulty: 3
});

// 表单校验规则
const formRules = {
  chapter: [{ required: true, message: '请输入章节', trigger: 'blur' }],
  node: [{ required: true, message: '请输入节点', trigger: 'blur' }],
  knowledge: [{ required: true, message: '请输入知识点', trigger: 'blur' }],
  mastery: [{ required: true, message: '请选择掌握程度', trigger: 'change' }],
  difficulty: [{ required: true, message: '请选择难度系数', trigger: 'change' }]
};

// 批量导入表单
const importForm = ref({
  message: '',
  subjectId: null,
  provider: 'deepseek'
});

// 分页相关
const currentPage = ref(1);
const pageSize = ref(10);
const searchKeyword = ref('');
const filterChapter = ref(null);
const filterMastery = ref(null);

// 选中的章节相关数据
const selectedChapterId = ref(null);
const selectedChapterName = ref('');
const selectedChapterText = ref('');
const selectedChapterKnowledgeCount = ref(0);

// 筛选后的数据
const filteredData = computed(() => {
  let result = graphDataList.value;
  
  // 关键字搜索
  if (searchKeyword.value) {
    const keyword = searchKeyword.value.toLowerCase();
    result = result.filter(item => 
      item.knowledge.toLowerCase().includes(keyword)
    );
  }
  
  // 章节筛选
  if (filterChapter.value) {
    result = result.filter(item => item.chapter === filterChapter.value);
  }
  
  // 掌握程度筛选
  if (filterMastery.value) {
    result = result.filter(item => item.mastery === filterMastery.value);
  }
  
  return result;
});

// 当前页数据
const paginatedData = computed(() => {
  const startIndex = (currentPage.value - 1) * pageSize.value;
  return filteredData.value.slice(startIndex, startIndex + pageSize.value);
});

// 获取所有章节选项
const chapterOptions = computed(() => {
  const chapters = new Set();
  graphDataList.value.forEach(item => chapters.add(item.chapter));
  return Array.from(chapters).sort((a, b) => a - b);
});

// 处理搜索
const handleSearch = () => {
  currentPage.value = 1; // 重置到第一页
};

// 处理筛选
const handleFilter = () => {
  currentPage.value = 1; // 重置到第一页
};

// 处理每页数量变化
const handleSizeChange = (val) => {
  pageSize.value = val;
  currentPage.value = 1; // 重置到第一页
};

// 处理页码变化
const handleCurrentChange = (val) => {
  currentPage.value = val;
};

// 获取学科列表
const getSubjectList = async () => {
  try {
    const response = await getSubjects(JSON.parse(localStorage.getItem('user')).id,1,100);
    if (response.code === 200) {
      subjectList.value = response.data.list;
      if (subjectList.value.length > 0) {
        selectedSubject.value = subjectList.value[2].id;
        handleSubjectChange();
      }
    } else {
      ElMessage.error(response.data.message || '获取学科列表失败');
    }
  } catch (error) {
    console.error('获取学科列表失败', error);
    ElMessage.error('获取学科列表失败');
  }
};

// 根据学科ID获取知识图谱数据
const getGraphData = async (subjectId) => {
  if (!subjectId) return;
  
  loading.value = true;
  try {
    const response = await getGraphDataBySubjectId(subjectId);
    if (response.code === 200) {
      graphDataList.value = response.data;
      // 重置分页和筛选
      currentPage.value = 1;
      searchKeyword.value = '';
      filterChapter.value = null;
      filterMastery.value = null;
      
      if (displayMode.value === 'chart') {
        nextTick(() => {
          initChart();
        });
      }
    } else {
      ElMessage.error(response.data.message || '获取知识图谱数据失败');
    }
  } catch (error) {
    console.error('获取知识图谱数据失败', error);
    ElMessage.error('获取知识图谱数据失败');
  } finally {
    loading.value = false;
  }
};

// 学科变更处理
const handleSubjectChange = () => {
  // 先销毁当前的图表实例
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
  getGraphData(selectedSubject.value);
};

// 展示模式变更处理
const handleModeChange = () => {
  if (displayMode.value === 'chart') {
    nextTick(() => {
      initChart();
    });
  }
};

// 初始化图表
const initChart = () => {
  if (!graphDataList.value.length) return;
  
  // 获取DOM元素
  const chartDom = document.getElementById('knowledgeChart');
  if (!chartDom) return;
  
  // 初始化图表
  chartInstance = echarts.init(chartDom);
  
  // 处理数据
  const nodes = [];
  const links = [];
  const chapters = {};
  const nodesMap = {};
  const chapterIds = [];
  const nodeStatus = ref({});  // 使用ref让它具有响应性
  
  // 添加中心学科节点
  const subjectId = `subject-${selectedSubject.value}`;
  const subjectName = subjectList.value.find(s => s.id === selectedSubject.value)?.name || '学科';
  
  // 计算放射状布局的位置
  // 计算每种类型节点的数量，用于合理分配位置
  const chapterCount = new Set();
  graphDataList.value.forEach(item => {
    chapterCount.add(item.chapter);
  });
  const totalChapters = chapterCount.size;
  
  // 添加中心学科节点
  nodes.push({
    id: subjectId,
    name: subjectName,
    symbolSize: 80,
    category: 3, // 新类别：学科
    itemStyle: {
      color: 'rgb(225, 49, 47)'  // 红色
    },
    label: {
      show: true,
      position: 'inside',
      formatter: '{b}',
      color: '#fff',
      fontSize: 14,
      fontWeight: 'normal'
    },
    fixed: true,  // 固定中心节点
    x: 0,         // 中心位置
    y: 0
  });
  
  // 第一步：构建三层结构（章-节-知识点）
  let chapterIndex = 0;
  const angleStep = (2 * Math.PI) / totalChapters;  // 平均分布角度
  const chapterRadius = 300;  // 章节距离中心的半径
  const nodeRadius = 500;     // 小节距离中心的半径，增加距离避免重叠
  const knowledgeRadius = 700; // 知识点距离中心的半径，进一步增加距离
  
  graphDataList.value.forEach(item => {
    const chapterId = `chapter-${item.chapter}`;
    const nodeId = `node-${item.chapter}-${item.node}`;
    const knowledgeId = `knowledge-${item.id}`;
    
    // 1. 添加章节点
    if (!chapters[item.chapter]) {
      chapters[item.chapter] = true;
      chapterIds.push(chapterId);
      
      // 计算章节节点的位置（环形均匀分布）
      const angle = chapterIndex * angleStep;
      const x = Math.cos(angle) * chapterRadius;
      const y = Math.sin(angle) * chapterRadius;
      
      nodes.push({
        id: chapterId,
        name: `第${item.chapter}章`,
        symbolSize: 50,  // 减小章节节点尺寸
        category: 0,  // 章
        itemStyle: {
          color: 'rgb(67, 96, 176)'  // 蓝色
        },
        label: {
          show: true,
          position: 'inside',
          formatter: '{b}',
          color: '#fff',
          fontSize: 12,
          fontWeight: 'normal'
        },
        fixed: false,  // 改为不固定，让力导向布局调整
        x: x,          // 设置初始x坐标
        y: y           // 设置初始y坐标
      });
      
      // 连接学科和章节，添加关系名称
      links.push({
        source: subjectId,
        target: chapterId,
        name: '包含', // 添加关系名称
        lineStyle: {
          color: '#ccc',
          width: 1,
          opacity: 0.8
        }
      });
      
      chapterIndex++;
    }
    
    // 2. 添加节点（小节）
    if (!nodesMap[nodeId]) {
      nodesMap[nodeId] = true;
      
      // 为小节计算位置，与章节接近但略微偏移
      const chapterAngle = chapterIds.indexOf(chapterId) * angleStep;
      const offsetAngle = chapterAngle + (Math.random() * 0.2 - 0.1); // 添加小偏移
      const x = Math.cos(offsetAngle) * nodeRadius;
      const y = Math.sin(offsetAngle) * nodeRadius;
      
      nodes.push({
        id: nodeId,
        name: `${item.chapter}.${item.node}`,
        symbolSize: 40,  // 减小小节节点尺寸
        category: 1,  // 节
        itemStyle: {
          color: 'rgb(108, 183, 110)'  // 绿色
        },
        label: {
          show: true,
          position: 'inside',
          formatter: '{b}',
          color: '#333',
          fontSize: 10,
          fontWeight: 'normal'
        },
        fixed: false,  // 改为不固定，让力导向布局调整
        x: x,         // 设置初始x坐标
        y: y          // 设置初始y坐标
      });
      
      // 连接章和节，添加关系名称
      links.push({
        source: chapterId,
        target: nodeId,
        name: '包含', // 添加关系名称
        lineStyle: {
          color: '#ccc',
          width: 1,
          opacity: 0.8
        }
      });
      
      // 默认所有节点为展开状态
      if (!nodeStatus.value[chapterId]) {
        nodeStatus.value[chapterId] = false; // 默认章节展开
      }
      
      if (!nodeStatus.value[nodeId]) {
        nodeStatus.value[nodeId] = false; // 默认节点展开
      }
    }
    
    // 3. 添加知识点节点
    // 为知识点计算位置，在相应小节附近
    const nodeAngle = chapterIds.indexOf(chapterId) * angleStep;
    const knowledgeOffsetAngle = nodeAngle + (Math.random() * 0.3 - 0.15); // 更大的随机偏移
    const x = Math.cos(knowledgeOffsetAngle) * knowledgeRadius;
    const y = Math.sin(knowledgeOffsetAngle) * knowledgeRadius;
    
    nodes.push({
      id: knowledgeId,
      name: item.knowledge,
      symbolSize: 30,  // 减小知识点节点尺寸
      category: 2,  // 知识点
      difficulty: item.difficulty,
      mastery: item.mastery,
      parentNodeId: nodeId,  // 记录父节点
      chapterId: chapterId,  // 记录所属章节ID，用于章节收起功能
      itemStyle: {
        color: 'rgb(249, 186, 86)'  // 橙色
      },
      label: {
        show: true,
        position: 'inside',  // 文字放在节点内部
        formatter: '{b}',
        color: '#333',
        fontSize: 8,  // 减小字体
        fontWeight: 'normal'
      },
      fixed: false,   // 改为不固定，让力导向布局调整
      x: x,          // 设置初始x坐标
      y: y           // 设置初始y坐标
    });
    
    // 连接节和知识点，添加关系名称
    links.push({
      source: nodeId,
      target: knowledgeId,
      name: '包含', // 添加关系名称
      lineStyle: {
        color: '#ccc',
        width: 1,
        opacity: 0.8
      }
    });
  });
  
  // 图表配置
  const option = {
    title: {
      text: `${subjectList.value.find(s => s.id === selectedSubject.value)?.name}知识图谱`,
      subtext: '点击节点可以展开/收起',
      left: 'center'
    },
    tooltip: {
      formatter: function(params) {
        if (params.dataType === 'node') {
          const data = params.data;
          if (data.category === 3) {
            return `<strong>${data.name}</strong>`;
          } else if (data.category === 0) {
            return `${data.name}`;
          } else if (data.category === 1) {
            return `${data.name} 节`;
          } else {
            return `
              <div>
                <p><strong>${data.name}</strong></p>
                <p>掌握程度: ${data.mastery || '未设置'}</p>
                <p>难度系数: ${data.difficulty || '未设置'}/3</p>
              </div>
            `;
          }
        }
        return '';
      }
    },
    legend: {
      data: ['学科', '章', '节', '知识点'],
      orient: 'vertical',
      right: 10,
      top: 20
    },
    animationDuration: 1500,
    animationEasingUpdate: 'quinticInOut',
    series: [
      {
        type: 'graph',
        layout: 'force',  // 使用力导向布局
        data: nodes,
        links: links,
        categories: [
          { name: '章' },
          { name: '节' },
          { name: '知识点' },
          { name: '学科' }
        ],
        roam: true,
        draggable: true,
        // 设置全局标签，放在连接线上
        edgeLabel: {
          show: true,
          formatter: function(params) {
            return params.data.name || '';
          },
          fontSize: 10,
          color: '#666',
          position: 'middle'
        },
        force: {
          initLayout: 'none',   // 使用我们预设的初始位置
          repulsion: 300,       // 适当的斥力，防止节点重叠
          edgeLength: 100,      // 较短的理想边长
          gravity: 0.05,        // 适当引力，使布局更紧凑
          friction: 0.3,        // 适当摩擦力，减少过度振荡
          layoutAnimation: true // 启用布局动画
        },
        edgeSymbol: ['none', 'none'],
        edgeSymbolSize: [0, 0],
        lineStyle: {
          color: '#ccc',
          width: 1,
          opacity: 0.8,
          curveness: 0  // 直线连接
        },
        itemStyle: {
          borderWidth: 1,
          borderColor: '#fff'
        },
        emphasis: {
          focus: 'adjacency',
          lineStyle: {
            width: 2
          },
          itemStyle: {
            shadowBlur: 10,
            shadowColor: 'rgba(0, 0, 0, 0.2)'
          }
        }
      }
    ]
  };
  
  // 设置图表选项
  chartInstance.setOption(option);
  
  // 初始化时应用节点状态
  const initialNodes = generateNodesWithStatus(nodes, nodeStatus.value);
  const initialLinks = generateLinksWithStatus(links, nodes, nodeStatus.value);
  
  // 更新图表
  chartInstance.setOption({
    series: [{
      data: initialNodes,
      links: initialLinks
    }]
  });
  
  // 修改点击事件处理收起/展开
  chartInstance.on('click', function(params) {
    // 点击"章"类型节点 - 收起/展开该章下所有节点
    if (params.dataType === 'node' && params.data.category === 0) { 
      const chapterId = params.data.id;
      const isExpanded = nodeStatus.value[chapterId]; // 获取当前状态
      
      // 切换展开/收起状态
      nodeStatus.value[chapterId] = !isExpanded;
      
      // 处理章节选择 - 确保在状态切换后调用
      handleChapterSelect(chapterId, params.data.name);
      
      // 找出此章下的所有节点
      const childrenNodes = nodes.filter(node => 
        node.category === 1 && node.id.startsWith(chapterId.replace('chapter-', 'node-'))
      );
      
      // 找出与这些节点相关的连接
      const childrenNodeLinks = links.filter(link => 
        childrenNodes.some(node => node.id === link.target)
      );
      
      // 找出所有与这一章相关的知识点
      const childrenKnowledgeNodes = nodes.filter(node => 
        node.category === 2 && node.chapterId === chapterId
      );
      
      // 找出与这些知识点相关的连接
      const childrenKnowledgeLinks = links.filter(link => 
        childrenKnowledgeNodes.some(node => node.id === link.target)
      );
      
      // 为每个"节"也保存状态
      childrenNodes.forEach(node => {
        nodeStatus.value[node.id] = !isExpanded; // 和章节保持一致
      });
      
      // 完全重新生成节点和连接数据，根据当前的全局状态
      const newNodes = generateNodesWithStatus(nodes, nodeStatus.value);
      const newLinks = generateLinksWithStatus(links, nodes, nodeStatus.value);
      
      // 更新图表
      chartInstance.setOption({
        series: [{
          data: newNodes,
          links: newLinks
        }]
      });
    }
    // 点击"节"类型节点 - 收起/展开该节下的知识点
    else if (params.dataType === 'node' && params.data.category === 1) { 
      const nodeId = params.data.id;
      const isExpanded = nodeStatus.value[nodeId]; // 获取当前状态
      
      // 切换展开/收起状态
      nodeStatus.value[nodeId] = !isExpanded;
      
      // 完全重新生成节点和连接数据，根据当前的全局状态
      const newNodes = generateNodesWithStatus(nodes, nodeStatus.value);
      const newLinks = generateLinksWithStatus(links, nodes, nodeStatus.value);
      
      // 更新图表
      chartInstance.setOption({
        series: [{
          data: newNodes,
          links: newLinks
        }]
      });
    }
  });
  
  // 添加辅助函数，根据所有节点状态重新生成节点数据
  function generateNodesWithStatus(originalNodes, statusObj) {
    return originalNodes.map(node => {
      // 章节节点 - 总是显示
      if (node.category === 0) {
        return node;
      }
      // 节点 - 仅当其父章节展开时才显示
      else if (node.category === 1) {
        const parentChapterId = node.id.split('-')[1]; // 从node-1-2提取1
        const chapterId = `chapter-${parentChapterId}`;
        const isParentExpanded = statusObj[chapterId];
        
        return {
          ...node,
          symbolSize: isParentExpanded ? 40 : 0, // 更新为与上面一致的尺寸
          label: {
            ...node.label,
            show: isParentExpanded
          }
        };
      }
      // 知识点 - 仅当其父章节和父节点都展开时才显示
      else if (node.category === 2) {
        const parentNodeExpanded = statusObj[node.parentNodeId];
        const parentChapterExpanded = statusObj[node.chapterId];
        const shouldShow = parentNodeExpanded && parentChapterExpanded;
        
        return {
          ...node,
          symbolSize: shouldShow ? 30 : 0, // 更新为与上面一致的尺寸
          label: {
            ...node.label,
            show: shouldShow
          }
        };
      }
      return node;
    });
  }
  
  // 添加辅助函数，根据所有节点状态重新生成连接数据
  function generateLinksWithStatus(originalLinks, originalNodes, statusObj) {
    return originalLinks.map(link => {
      // 获取源节点和目标节点
      const sourceNode = originalNodes.find(n => n.id === link.source);
      const targetNode = originalNodes.find(n => n.id === link.target);
      
      // 如果目标节点是隐藏的，连接线也应该隐藏
      if (targetNode) {
        if (targetNode.category === 1) {
          // 节点 - 检查其父章节状态
          const parentChapterId = targetNode.id.split('-')[1];
          const chapterId = `chapter-${parentChapterId}`;
          const isVisible = statusObj[chapterId];
          
          return {
            ...link,
            lineStyle: {
              ...link.lineStyle,
              opacity: isVisible ? 1 : 0,
              width: isVisible ? 1 : 0
            }
          };
        } 
        else if (targetNode.category === 2) {
          // 知识点 - 检查其父节点和父章节状态
          const parentNodeExpanded = statusObj[targetNode.parentNodeId];
          const parentChapterExpanded = statusObj[targetNode.chapterId];
          const isVisible = parentNodeExpanded && parentChapterExpanded;
          
          return {
            ...link,
            lineStyle: {
              ...link.lineStyle,
              opacity: isVisible ? 1 : 0,
              width: isVisible ? 1 : 0
            }
          };
        }
      }
      
      // 章节间的连接总是可见的
      if (sourceNode && targetNode && 
          sourceNode.category === 0 && targetNode.category === 0) {
        return link;
      }
      
      return link;
    });
  }
  
  // 添加拖拽事件
  chartInstance.on('graphroam', function() {
    chartInstance.setOption({
      series: [{
        roam: true,
        draggable: true
      }]
    });
  });

  // 添加布局完成事件处理程序
  chartInstance.on('rendered', function() {
    // 防止节点一直漂移，在设定时间后固定位置
    setTimeout(() => {
      const option = chartInstance.getOption();
      if (option.series && option.series[0] && option.series[0].data) {
        // 修改中心节点为固定
        const newData = option.series[0].data.map(node => {
          if (node.id === subjectId) {
            return {
              ...node,
              fixed: true
            };
          }
          return node;
        });
        
        // 应用修改
        chartInstance.setOption({
          series: [{
            data: newData
          }]
        });
      }
    }, 3000); // 3秒后固定中心节点
  });
};

// 处理章节选择
const handleChapterSelect = (chapterId, chapterName) => {
  console.log("选中章节:", chapterId, chapterName);
  
  selectedChapterId.value = chapterId;
  selectedChapterName.value = chapterName;
  
  // 从chapterId中提取章节编号
  const chapterNumber = chapterId.replace('chapter-', '');
  
  // 提取该章节下的所有知识点
  const chapterKnowledgePoints = graphDataList.value.filter(item => 
    item.chapter == chapterNumber // 使用==而不是===以允许类型不同的比较
  );
  
  console.log("找到知识点数量:", chapterKnowledgePoints.length);
  
  // 计算知识点数量
  selectedChapterKnowledgeCount.value = chapterKnowledgePoints.length;
  
  // 拼接知识点文本
  if (chapterKnowledgePoints.length > 0) {
    const subjectName = subjectList.value.find(s => s.id === selectedSubject.value)?.name || '';
    let text = `${subjectName}${chapterName}知识点：\n`;
    
    // 按节点分组整理知识点
    const nodeGroups = {};
    chapterKnowledgePoints.forEach(item => {
      if (!nodeGroups[item.node]) {
        nodeGroups[item.node] = [];
      }
      nodeGroups[item.node].push(item);
    });
    
    // 按节点顺序拼接知识点
    Object.keys(nodeGroups).sort((a, b) => Number(a) - Number(b)).forEach(node => {
      text += `\n${chapterName}.${node} 节：\n`;
      nodeGroups[node].forEach(item => {
        text += `- ${item.knowledge}`;
        if (item.mastery) {
          text += `（掌握程度：${item.mastery}`;
          if (item.difficulty) {
            text += `，难度：${item.difficulty}）`;
          } else {
            text += `）`;
          }
        }
        text += '\n';
      });
    });
    
    selectedChapterText.value = text;
    console.log("生成的文本:", text);
    
    // 自动滚动到选中的章节信息区域
    if (displayMode.value === 'table') {
      nextTick(() => {
        const selectedContentEl = document.querySelector('.selected-content');
        if (selectedContentEl) {
          selectedContentEl.scrollIntoView({ behavior: 'smooth' });
        }
      });
    }
  } else {
    selectedChapterText.value = '';
    ElMessage.warning('该章节下没有知识点');
  }
};

// 处理表格模式下的章节导出
const handleExportChapter = () => {
  if (!filterChapter.value) {
    ElMessage.warning('请先选择一个章节');
    return;
  }
  
  // 构造章节ID和名称
  const chapterId = `chapter-${filterChapter.value}`;
  const chapterName = `第${filterChapter.value}章`;
  
  // 调用现有的章节选择处理函数
  handleChapterSelect(chapterId, chapterName);
};

// 修改保存到题目生成区的方法
const saveToTextContent = () => {
  if (selectedChapterText.value) {
    // 修正方法名为setText
    textContentStore.setTextContent(selectedChapterText.value);
    console.log("保存的内容:", selectedChapterText.value);
    ElMessage.success('已保存到题目生成区');
  } else {
    ElMessage.warning('没有选中的章节知识点');
  }
};

// 清除选择
const clearSelectedChapter = () => {
  selectedChapterId.value = null;
  selectedChapterName.value = '';
  selectedChapterText.value = '';
  selectedChapterKnowledgeCount.value = 0;
};

// 添加知识点
const handleAdd = () => {
  dialogType.value = 'add';
  formData.value = {
    id: null,
    subjectId: selectedSubject.value,
    chapter: 1,
    node: 1,
    knowledge: '',
    mastery: '理解',
    difficulty: 3
  };
  dialogVisible.value = true;
};

// 编辑知识点
const handleEdit = (row) => {
  dialogType.value = 'edit';
  formData.value = { ...row };
  dialogVisible.value = true;
};

// 删除知识点
const handleDelete = (row) => {
  ElMessageBox.confirm('确定要删除这个知识点吗？', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(async () => {
    try {
      const response = await deleteGraphData(row.id);
      if (response.code === 200) {
        ElMessage.success('删除成功');
        getGraphData(selectedSubject.value);
      } else {
        ElMessage.error(response.message || '删除失败');
      }
    } catch (error) {
      console.error('删除知识点失败', error);
      ElMessage.error('删除知识点失败');
    }
  }).catch(() => {});
};

// 提交表单
const submitForm = async () => {
  if (!formRef.value) return;
  
  await formRef.value.validate(async (valid) => {
    if (valid) {
      try {
        // 设置学科ID
        formData.value.subjectId = selectedSubject.value;
        
        let response;
        if (dialogType.value === 'add') {
          response = await addGraphData(formData.value);
        } else {
          response = await updateGraphData(formData.value);
        }
        
        if (response.code === 200) {
          ElMessage.success(dialogType.value === 'add' ? '添加成功' : '更新成功');
          dialogVisible.value = false;
          getGraphData(selectedSubject.value);
        } else {
          ElMessage.error(response.message || `${dialogType.value === 'add' ? '添加' : '更新'}失败`);
        }
      } catch (error) {
        console.error(`${dialogType.value === 'add' ? '添加' : '更新'}知识点失败`, error);
        ElMessage.error(`${dialogType.value === 'add' ? '添加' : '更新'}知识点失败`);
      }
    }
  });
};

// 批量导入
const handleBatchImport = () => {
  importForm.value = {
    message: '',
    subjectId: selectedSubject.value,
    provider: 'deepseek'
  };
  importDialogVisible.value = true;
};

// 提交批量导入
const submitImport = async () => {
  if (!importForm.value.message) {
    ElMessage.warning('请输入知识点内容');
    return;
  }
  
  importing.value = true;
  let abortController = new AbortController();
  
  try {
    const graphRequest = {
      message: importForm.value.message,
      subjectId: selectedSubject.value
    };
    
    const provider = localStorage.getItem('aiModel') || 'deepseek';
    
    // 设置一个超时处理，如果15分钟后仍在导入，则中止
    const timeoutId = setTimeout(() => {
      if (importing.value) {
        ElMessage.warning('导入时间过长，已自动中止');
        abortController.abort();
        importing.value = false;
      }
    }, 900000); // 15分钟超时
    
    try {
      const response = await generateGraphDataStream(graphRequest, provider);
      
      clearTimeout(timeoutId);
      
      if (response.code === 200) {
        ElMessage.success(response.message || '导入成功');
        importDialogVisible.value = false;
        getGraphData(selectedSubject.value);
      } else {
        ElMessage.error(response.message || '导入失败');
      }
    } catch (error) {
      if (error.name === 'AbortError') {
        console.log('请求被中止');
      } else {
        console.error('批量导入失败', error);
        ElMessage.error('批量导入失败: ' + (error.message || '未知错误'));
      }
    } finally {
      clearTimeout(timeoutId);
    }
  } catch (error) {
    console.error('批量导入准备阶段失败', error);
    ElMessage.error('批量导入失败: ' + error.message);
  } finally {
    importing.value = false;
  }
};

// 获取掌握程度标签类型
const getMasteryTagType = (mastery) => {
  return masteryTagMap[mastery] || 'info';
};

// 监听窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize();
  }
};

// 监听展示模式变化，重新初始化图表
watch(displayMode, (newVal) => {
  if (newVal === 'chart') {
    nextTick(() => {
      initChart();
    });
  }
});

// 监听窗口大小变化
window.addEventListener('resize', handleResize);

// 组件卸载时清除图表实例和事件监听
onMounted(() => {
  getSubjectList();
  if (route.query.subjectId) {
    selectedSubject.value = route.query.subjectId;
    // getGraphData(selectedSubject.value);
  }
  // initChart()
});

// 组件卸载时清除事件监听
onUnmounted(() => {
  window.removeEventListener('resize', handleResize);
  if (chartInstance) {
    chartInstance.dispose();
  }
});

// 添加复制到剪贴板功能
const copyToClipboard = () => {
  if (selectedChapterText.value) {
    navigator.clipboard.writeText(selectedChapterText.value)
      .then(() => {
        ElMessage.success('内容已复制到剪贴板');
      })
      .catch(err => {
        console.error('复制失败: ', err);
        ElMessage.error('复制失败，请手动复制');
      });
  } else {
    ElMessage.warning('没有内容可复制');
  }
};
</script>

<style scoped>
/* 基础样式 */
.graph-container {
  padding: 24px;
  background-color: white;
  min-height: calc(100vh - 60px);
}

/* 顶部标题和操作区域 */
.top-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
}

.page-title {
  display: flex;
  flex-direction: column;
}

.page-title h2 {
  margin: 0;
  font-size: 24px;
  font-weight: 600;
  color: #303133;
}

.subtitle {
  margin: 4px 0 0 0;
  font-size: 14px;
  color: #909399;
}

.top-actions {
  display: flex;
  gap: 16px;
  align-items: center;
}

.subject-select {
  width: 160px;
}

.display-toggle {
  margin-left: 8px;
}

/* 内容卡片 */
.main-content-card {
  margin-bottom: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  overflow: hidden;
}

/* 表格视图样式 */
.table-view {
  display: flex;
  flex-direction: column;
}

.table-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  background-color: #fff;
  border-bottom: 1px solid #ebeef5;
}

.filter-section {
  display: flex;
  align-items: center;
  gap: 16px;
}

.search-input {
  width: 240px;
}

.filter-dropdowns {
  display: flex;
  gap: 12px;
}

.filter-select {
  width: 140px;
}

.action-buttons {
  display: flex;
  gap: 12px;
}

.export-btn {
  margin-right: 8px;
}

.knowledge-table {
  width: 100%;
}

.table-actions {
  display: flex;
  justify-content: center;
  gap: 8px;
}

.pagination-wrapper {
  padding: 16px 20px;
  display: flex;
  justify-content: flex-end;
  background-color: #fff;
  border-top: 1px solid #ebeef5;
}

/* 图表视图样式 */
.chart-view {
  padding: 0;
  height: calc(100vh - 220px);
}

.knowledge-chart {
  width: 100%;
  height: 100%;
  min-height: 600px;
}

/* 选中章节面板样式 */
.selected-chapter-panel {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
  margin-bottom: 20px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.header-left {
  display: flex;
  align-items: center;
  gap: 12px;
}

.header-left h3 {
  margin: 0;
  font-size: 18px;
  font-weight: 600;
  color: #303133;
}

.header-actions {
  display: flex;
  gap: 12px;
  align-items: center;
}

.preview-content {
  background-color: #f9f9fa;
  border-radius: 6px;
  padding: 4px;
}

.preview-textarea {
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
  background-color: #f9f9fa;
}

.preview-textarea :deep(.el-textarea__inner) {
  background-color: #f9f9fa;
  border: none;
  padding: 16px;
  color: #303133;
  line-height: 1.6;
}

/* 对话框样式 */
:deep(.knowledge-dialog .el-dialog__body) {
  padding: 20px 30px;
}

:deep(.import-dialog .el-dialog__body) {
  padding: 0 30px 20px;
}

.import-instructions {
  margin-bottom: 20px;
}

.import-textarea {
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .filter-section {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .top-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
  }
  
  .top-actions {
    width: 100%;
    justify-content: space-between;
  }
}

@media (max-width: 768px) {
  .table-toolbar {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }
  
  .filter-dropdowns {
    flex-direction: column;
    gap: 12px;
  }
  
  .action-buttons {
    justify-content: space-between;
  }
  
  .panel-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }
  
  .header-actions {
    width: 100%;
    justify-content: space-between;
  }
}

/* 可以添加一些图标相关的样式 */
.el-icon {
  margin-right: 4px;
  vertical-align: middle;
}

.el-button--small .el-icon {
  font-size: 14px;
}

/* 修复圆形按钮中图标的位置 */
.el-button.is-circle .el-icon {
  margin-right: 0;
}
</style>